// 代码参考：https://oshwhub.com/shukkkk/esp32s3_tft_mp3
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include <WiFi.h>
#include "time.h"

#include "global_config.h"
#include <ArduinoWebsockets.h>
#include <ArduinoJson.h>

#include "SPI.h"
#include <HTTPClient.h>

#include <esp_system.h>
#include "bsp_i2s.h"

#include "bsp_ntp.h"
#include "app_xf.h"


extern WiFiUDP ntpUDP;
extern NTPClient timeClient;


// 录音缓存区
extern int16_t audioData[2560];
extern int16_t *pcm_data; 
extern uint recordingSize;

extern String stttext;


Adafruit_NeoPixel pixels(PIX_NUM, PIN_PIXS, NEO_GRB + NEO_KHZ800);



// char* psramBuffer = (char*)ps_malloc(512000);
String odl_answer;

String answer_list[10];
uint8_t answer_list_num = 0;
bool answer_ste = 0;

using namespace websockets;
WebsocketsClient client;    //WebSocket 客户端

bool timeste = 0;



void setup()
{
  Serial.begin(115200);
  
  //LED灯？
  pinMode(48, OUTPUT);
  digitalWrite(48, HIGH);

  //链接Wifi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //初始化 ntp 客户端，得到日期时间
  setup_ntp_client();
  getDateTime();

  //LED灯
  pixels.begin();
  pixels.setBrightness(8);
  // 熄灭2812
  pixels.clear();
  pixels.show();

  //初始化 I2S 设备 INMP441
  Serial.println("Setup I2S ...");
  i2s_install();
  i2s_setpin();
  esp_err_t err = i2s_start(I2S_PORT_0);
  if (err != ESP_OK)
  {
    Serial.printf("I2S start failed (I2S_PORT_0): %d\n", err);
    while (true)
      ;
  }
  else
  {
    Serial.printf("I2S start OK!\r\n");
  }

  // run callback when messages are received 
  // 设置 Websocket 客户端的回调函数
  client.onMessage(handleWebSocketMessage);
  Serial.printf("Please hit keyboard input '1' to start Audio capturing!\r\n");
}


void loop()
{
  if (Serial.available())
  {
    // delay(20);
    if (Serial.read() == '1')
    {
      stttext = "";
      Serial.println("Recording...");
      
      
      // 分配 pcm_data 内存，分配的大小为 (16000 * 10) * 16 bit（2B） = 320kB= 0.3125MB
      pcm_data = (int16_t *)ps_malloc(BUFFER_SIZE * sizeof(int16_t));
      if (!pcm_data)
      {
        Serial.println("Failed to allocate memory for pcm_data from PSRAM");
        return;
      }

      recordingSize = 0;
      size_t bytes_read = 0;
      // uint16_t x = 0, y = 0;



      /**
       * @brief  
       * recordingSize：采样得到的字节数的1/2 或者说uint16_t 的个数(每次采样，深度为16bit，得到2字节)
       * recordTimeSeconds：此处为3s
       * SAMPLE_RATE：此处为16k 
       * recordTimeSeconds * SAMPLE_RATE 表示i2s采集，经过3s所得到的 uint16_t 的个数 
       */
      while (recordingSize < recordTimeSeconds * SAMPLE_RATE)
      {
       // 开始循环录音，将录制结果保存在pcm_data中
        esp_err_t result = i2s_read(I2S_PORT_0, audioData, sizeof(audioData), &bytes_read, portMAX_DELAY);
        memcpy(pcm_data + recordingSize/*pcm_data 是 uint16_t 类型的指针，因此recordingSize不需要乘2*/, 
          audioData, 
          bytes_read);
        recordingSize += bytes_read / 2; //此处除以2，很有意思
      }

      Serial.printf("Total bytes read: %d\n", recordingSize);
      Serial.println("Recording complete.");
      STTsend(); // STT请求开始
      free(pcm_data);
    } 
  }
        
  if (client.available())
  {   
    client.poll();
  }
  delay(50);
}